package com_github_lib_base.ext.rv

import android.R.attr.value
import android.util.Log
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import kotlin.reflect.KClass

fun RecyclerView.setup(
    items: List<Any>,
    builderAction: DslAdapterBuilder.() -> Unit
) {
    val typeConfig = mutableMapOf<KClass<*>, (Any) -> Int>()
    var bindAction: (BindAdapter) -> Unit = {}

    val builder = object : DslAdapterBuilder {
        override fun <T : Any> addType(clazz: KClass<T>, layoutProvider: (T) -> Int) {
            @Suppress("UNCHECKED_CAST")
            typeConfig[clazz] = { item -> layoutProvider(item as T) }
        }

        override fun <T : Any> addType(clazz: KClass<T>, layoutResId: Int) {
            typeConfig[clazz] = { _: Any -> layoutResId }
        }

        override fun onBind(action: BindAdapter.() -> Unit) {
            bindAction = { context -> context.action() }
        }
    }

    builder.builderAction()
    adapter = DslAdapter(items.toMutableList(), typeConfig, bindAction)
}

// 添加或插入数据集合
fun RecyclerView.addModels(newItems: List<Any>, index: Int = -1) {
    val adapter = this.adapter as? DslAdapter ?: return
    val insertIndex = if (index in 0..adapter.items.size) index else adapter.items.size
    adapter.items.addAll(insertIndex, newItems)
    adapter.notifyItemRangeInserted(insertIndex, newItems.size)
}

fun RecyclerView.addModels(newItems: List<Any>, index: Int = -1, animation: Boolean = true) {
    val adapter = this.adapter as? DslAdapter ?: return
    if (newItems.isEmpty()) return

    // 确保数据是可变的
    val data = newItems.toMutableList()
    val itemCountBefore = adapter.items.size
    val insertIndex = if (index in 0..adapter.items.size) index else adapter.items.size

    // 插入数据
    adapter.items.addAll(insertIndex, data)

    // 通知更新
    if (animation) {
        adapter.notifyItemRangeInserted(insertIndex, data.size)
        // 强制更新装饰器，避免装饰器导致的偏移
        post { invalidateItemDecorations() }
    } else {
        adapter.notifyDataSetChanged()
    }

    // 如果插入到索引 0，滚动到顶部
    if (insertIndex == 0) {
        post {
            smoothScrollToPosition(0)
            //Log.d("RecyclerView", "Inserted at index 0, scrolled to position 0, first visible: ${layoutManager?.findFirstVisibleItemPosition()}")
        }
    }
}

// 替换当前所有数据
var RecyclerView.models: MutableList<Any>
    get() = (this.adapter as? DslAdapter)?.items ?: mutableListOf()
    set(value) {
        val adapter = this.adapter as? DslAdapter ?: return
        adapter.items.clear()
        adapter.items.addAll(value)
        adapter.notifyDataSetChanged()
    }

// 删除指定位置的数据项
fun RecyclerView.removeModelAt(position: Int) {
    val adapter = this.adapter as? DslAdapter ?: return
    if (position in adapter.items.indices) {
        adapter.items.removeAt(position)
        adapter.notifyItemRemoved(position)
    }
}

// 使用 DiffUtil 替换数据集合，自动比较新旧数据
fun RecyclerView.setDifferModels(newItems: List<Any>) {
    val adapter = this.adapter as? DslAdapter ?: return
    val oldItems = adapter.items.toList()
    adapter.items.clear()
    adapter.items.addAll(newItems)
    val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
        override fun getOldListSize(): Int = oldItems.size
        override fun getNewListSize(): Int = newItems.size
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldItem = oldItems[oldItemPosition]
            val newItem = newItems[newItemPosition]
            return when {
                oldItem.javaClass == newItem.javaClass && oldItem is HasId && newItem is HasId ->
                    oldItem.id == newItem.id
                else -> oldItem === newItem
            }
        }
        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldItems[oldItemPosition] == newItems[newItemPosition]
        }
    })
    diffResult.dispatchUpdatesTo(adapter)
}

// 辅助接口，用于标识具有唯一 ID 的数据项
interface HasId {
    val id: Any
}